﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "ComponentEditorGnufUI.h"
#include "GnufItemEvents.h"
#include "GnufUiCommonDef.h"
#include "IGnufWidget.h"
#include "IUiDocumentEventHandler.h"
#include "IUiViewEventHandler.h"
#include "IUndoRedoEventHandler.h"
#include "UniIdentity.h"

namespace gcmp {
    class IModelView;
    class IDocument;
    class IUiDocument;
    class IUiDocumentEventArgs;
    class IUiViewEventArgs;
}

namespace gnuf {
    class TreeBoard;
    class TreeNode;
    class NameValuePairs;
    class List;
}

namespace gfam {
    class DisplayAndPickFilterInitializerBase;
    class ElementCanBePickedInModifyAction;
    enum class FilterType;

    // replace BmDisplayFilterDialog
    class COMPONENT_EDITOR_GNUF_UI_EXPORT GnufDisplayAndPickFilterBoard final
        : public gnuf::IItemEventHandler
        , public gcmp::IUiDocumentEventHandler
        , public gcmp::IUiViewEventHandler
    {
    public:
        GnufDisplayAndPickFilterBoard();
        virtual ~GnufDisplayAndPickFilterBoard() {}

    public:
        void Initialize(gnuf::TreeBoard*, gnuf::NameValuePairs*);
        void RefreshPanel(gcmp::IUiDocument* pUIDoc);
        void ClearHide(gcmp::IUiDocument* pUIDoc);

    protected:
        // Inherits from gnuf::IItemEventHandler...
        virtual void onTreeItemIconButtonClicked(gnuf::TreeNode*, int iconIndex) override;

        // Inherits from gcmp::IUiDocumentEventHandler...
        virtual void On(gcmp::IUiDocumentEventArgs*) override;

        // Inherits from gcmp::IUiViewEventHandler...
        virtual void On(gcmp::IUiViewEventArgs*) override;

    private:
        void InitTree(gcmp::IDocument* pDoc);
        void UiInitFromFilter(gcmp::IDocument* pDoc);
        void UiInitToFilter(gcmp::IDocument* pDoc);
        gcmp::UniIdentity GetUniIdentityByTreeItemName(const std::wstring& name);
        void AddTreeItem(gcmp::IDocument* pDoc, gnuf::TreeNode* pItem, const std::wstring& name, const std::vector<gcmp::UniIdentity>& m_categoryIds, int startIndex, int endIndex);
        void AddChildTreeItem(gcmp::IDocument* pDoc, gnuf::TreeNode* pItem, const std::vector<gcmp::UniIdentity>& m_categoryIds);

        void setCheckStatus(gnuf::TreeNode* node, FilterType filterType, gnuf::CheckStatus status);

        void onDisplayIconClicked(gnuf::TreeNode* pItem, int index);
        void onPickIconClicked(gnuf::TreeNode* pItem, int index);
        void setFatherDisplayCheckStatusBySonCheckStatus(gnuf::TreeNode* pItemSon, FilterType filterType, const gnuf::CheckStatus& state, int index);
        void setNodePickedCategory(gfam::ElementCanBePickedInModifyAction * pElementCanBePickedByCategoryInModifyAction, gnuf::TreeNode* pItem, const gnuf::CheckStatus& state);

        gcmp::UniIdentity FindSelectedCategoryId(gnuf::TreeNode* pItem);

    private:
        bool m_bInitFilterRule;
        gnuf::TreeBoard* m_tree;
        gnuf::NameValuePairs* m_nameValuePairs;
        gcmp::OwnerPtr<DisplayAndPickFilterInitializerBase> m_initializer;
        std::map<std::wstring, gcmp::UniIdentity> m_nameToCategory;
        std::vector<gcmp::UniIdentity> m_categoryIds;
    };
}